#pragma once
#include "build_kernels_cuda.h"

namespace shermit {
namespace lbvh {
namespace GPU {


	__global__ void genBroadPhaseCollisionInadjacent(int leafSize, LBvhLeaves leaves, LBvhInteriors interiors, TriMesh_SOA<DeviceType::GPU> mesh, CollisionPair* cps, int* cpSize) {
		int idx = blockIdx.x * blockDim.x + threadIdx.x;
		if (idx >= leafSize - 1) return;
		//if (idx > 0) return;

		int node_i = idx; //leaf idx
		const auto bv_i = leaves.bv.getBV(node_i);
		int ia = leaves.primIdx[node_i];
		int3 fa = mesh.faces[ia];
		int t1 = 3 * ia;
		Point3f P1 = mesh.faceVertices[t1], P2 = mesh.faceVertices[t1 + 1], P3 = mesh.faceVertices[t1 + 2];
		//const BV bv_i = leaves.bv[node_i];
		//const BV bv_i = leaves.bv.getBV(interiors.rangeR[min(idx, leafSize - 2)]);


		// do sprouting
		int L = 0, R = 0;
		bool overlap = false;
		int interior_idx = 0;
		//BV t;
		for (int begin = idx + 1; begin < leafSize; begin++) {
			//printf("visit leaf %d\n", begin);
			L = leaves.segOffset[begin];
			//R = L + leaves.segLen[begin];
			R = begin == leafSize - 1 ? L : leaves.segOffset[begin + 1];
			//R = leaves.parent[begin];
			overlap = true;
			//if (R - L >= 6) {
			for (interior_idx = L; interior_idx < R; ++interior_idx) {
				//printf("visit interior %d\n", interior_idx);
				//if (interior_idx<0 || interior_idx >= leafSize - 1) printf("interior_idx: %d\n", interior_idx);
				//t = interiors.bv.getBV(interior_idx);
				//overlap = bv_i.overlap(t);
				overlap = interiors.bv.overlap(interior_idx, bv_i);
				//overlap = interiors.bv[interior_idx].overlap(bv_i);
				if (!overlap) {
					begin = interiors.rangeR[interior_idx];
					break;
				};
			}
			//}
			if (!overlap) continue;

			if (leaves.bv.overlap(begin, bv_i)) {

				int ib = leaves.primIdx[begin];
				int3 fb = mesh.faces[ib];

				if (fa.x == fb.x || fa.x == fb.y || fa.x == fb.z) {
					//begin++;
					continue;
				}
				if (fa.y == fb.x || fa.y == fb.y || fa.y == fb.z) {
					//begin++;
					continue;
				}
				if (fa.z == fb.x || fa.z == fb.y || fa.z == fb.z) {
					//begin++;
					continue;
				}
				//volatile int isad = ia;

				//int t2 = 3 * ib;
				//Point3f Q1 = mesh.faceVertices[t2], Q2 = mesh.faceVertices[t2 + 1], Q3 = mesh.faceVertices[t2 + 2];
				//if (triContact(P1, P2, P3, Q1, Q2, Q3)) {

					//printf("#self contact found at (%d, %d)\n", ia, ib);
				//}
				CollisionPair cp{ ia, ib };
				cps[atomicAdd(cpSize, 1)] = cp;
				//begin++;
				//continue;
			}
		}
	}
}
}
}